#ifndef _PHY_TX_H
#define _PHY_TX_H



/* TX state machine - states */
typedef enum
{
	PHY_TX_IDLE          = 0,        // Idle
	PHY_TX_START         = 1,        // Start
	PHY_TX_SYNCP         = 2,        // Preamble - SYNCP
	PHY_TX_SYNCM         = 3,        // Preamble - SYNCM
	PHY_TX_HDR           = 4,        // Header
	PHY_TX_DATA          = 5,        // Data
	PHY_TX_LAST          = 6,        // Data
	PHY_TX_FAIL          = 7,        // Fail
	NUM_PHY_TX_STATES    = 8
}PHY_tx_state_t;

/* TX state machine - events */
typedef enum
{
	PHY_TX_EVT_START      = 0,        // Start
	PHY_TX_EVT_RETRY      = 1,        // Retry
	PHY_TX_EVT_FAIL       = 2,        // Fail
	PHY_TX_EVT_DONE       = 3,        // Done
	NUM_PHY_TX_EVENTS     = 4
}PHY_tx_event_t;

typedef enum
{
	PHY_TX_CLEAR_STAT         = 0,        // Clear PHY TX statistics
	PHY_TX_SETMODE            = 1,
	NUM_PHY_TX_SETPARMS       = 2
}PHY_tx_setType_t;

/* Set data structure */
typedef union
{
	UINT16 roboMode;            // 0-PRIME; 1-ROBO
}PHY_txSetData_t;

typedef struct
{
	FSM_stateMachine_t  *sm_p;           // State machine pointer
	Uint32              ppduCnt;
	Uint32              ppduStartCnt;
	Uint16              txSize;
	volatile Uint16     ppduBusy;

	HAL_cbFunc_t        timerCb_p;       // ptr to callbacks for timer expiry

	UINT16              roboMode;        // 0-PRIME; 1-ROBO
}PHY_tx_handle_t;

/* TX PPDU parameter structure */
typedef struct
{
	UINT16              *ppduHdr_p;       // Pointer to MAC_H (PPDU header)
	UINT16              *ppduPld_p;       // Pointer to PPDU payload
	UINT16              length;           // Length of PPDU payload in bytes
	UINT16              level;            // TX level
	UINT16              mcs;              // TX modulation & coding scheme
	UINT32              txTime;           // TX time (in 10us)
}PHY_tx_ppdu_t;

typedef struct
{
	PHY_tx_ppdu_t   txPpdu[2];
	PHY_cbFunc_t    cb_p[2];
	Uint16          txQLen;
	Uint16          wrPtr;
	Uint16          rdPtr;
}PHY_txQueue_t;

typedef struct
{
	Uint32          ppduTime;
	Uint32          startTime;
	Uint32          startTimeLast;
	Uint32          preStartTime;
	Uint32          hdrStartTime;
	Uint32          dataStartTime;
	Uint32          dataStopTime;
}PHY_txTimeLog_t;

typedef struct
{
	UINT16              phyStatsTxDropCount; // # of times TX PHY drops packets
	UINT16              phyTxQLen;           // TX queue length
	UINT32              phyTxProcDelay;      // time in 10us between txPpdu() called to it's put in the channel
	UINT32              phyTxPacketCount;    // # TX packets
}PHY_tx_stat_t;

/* smart DMA BD definition */

typedef struct _SMART_BUF_DESC_s
{
   struct _SMART_BUF_DESC_s *pnext;

   uint16 *buf_p;
   Uint16 len;
} SBD_s;

typedef struct
{
	int16            upsScale;
    int16            txClip;
	PHY_cfft16_t     ifft_prmb_hnd;
	PHY_cfft16_t     ifft_hnd;
	PHY_fir_t        upsFir;
	
	int16            *bufBegin_p;
	int16            *bufUserBegin_p;
	int16            *bufEnd_p;
	int16            *bufA_p;
	int16            *bufB_p;
	int16            *intlvOut_p;
	int16            *modOut_p;
	int16            *upsIn_p;

	Uint16           *ppduHdr_p;
	Uint16           *ppduPld_p;
	Uint16           *ppduOrig_p;

	Uint16           numSamps;
	Uint16           numInBits;
	uint16           numHdrSymbols;    // PRIME-2; PRIME_ROBO-8
	Uint16           numDataSymbols;
	Uint16           numPldBits;
	Uint16           numPadBits;       // Coded pad bits
	Uint16           numCodedPldBits;
	Uint16           numBitsInSymbol;  //96*(mod+1); 96-DBPSK; 192-DQPSK; 288-D8PSK
	Uint16           symbCnt;
	Uint16           mod;
	Uint16           enc;
	Uint32           txTime;

	PHY_cnvEnc_t     cnvEnc;
	PHY_cbFunc_t     cb_p;

	PHY_txQueue_t    txQueue;

	PHY_txTimeLog_t  timeLog;

	PHY_tx_stat_t    stats;

	/* Suspend & resume */
	Uint16           txSuspend;
	PHY_cbFunc_t     txSuspendCb_p;

	/* For debug */
	Uint16           numBitsInLastSymb;
	Uint16           numWordsInLastSymb;

	volatile Uint16 *afeBuf_p[2];         // TX ping-pong buffer ready to be read
	Uint16          afeBufIdx;
    SINT16          prmbScale;
}PHY_tx_data_t;

/* Tx scratch buffer */
typedef struct
{
	SINT16 buf1[8];
	UINT16 buf2[168]; //store unpacked header and linearized BD data
	UINT16 buf3[96]; //for ROBO, stored coded header/4 (2 symbols) or coded data/4 (1 symbol)
	ComplexShort buf4[49]; //store the mod data for the first header symbol
	UINT16 ilvBuf[192]; //
}PHY_tx_scratchBuf_t;


PHY_status_t PHY_txSet(Uint16 setType, PHY_txSetData_t *setParms_p);
PHY_status_t PHY_tx_setStatClr(PHY_txSetData_t *getParms_p);
PHY_status_t PHY_tx_setRoboMode(PHY_txSetData_t *setParms_p);
PHY_status_t PHY_txInit(void);
PHY_status_t PHY_tx_start(void *data_p);
PHY_status_t PHY_tx_nop(void *data_p);
PHY_status_t PHY_tx_fail(void *data_p);
PHY_status_t PHY_txSmRun(void);
PHY_status_t PHY_tx_complete(void *data_p);
PHY_status_t PHY_tx_dataLast(void *data_p);
PHY_status_t PHY_tx_dataProc(void *data_p);
PHY_status_t PHY_tx_dataStart(void *data_p);
PHY_status_t PHY_tx_hdrProc(void *data_p);
PHY_status_t PHY_tx_hdrStart(void *data_p);
PHY_status_t PHY_tx_syncmProc(void *data_p);
PHY_status_t PHY_tx_syncmStart(void *data_p);
PHY_status_t PHY_tx_syncpProc(void *data_p);
PHY_status_t PHY_tx_syncpStart(void *data_p);
PHY_status_t PHY_txPpdu(PHY_tx_ppdu_t *ppdu, PHY_cbFunc_t cb_p);

#endif //_PHY_TX_H